using AdminSG3L.Domain.Entities;
using AdminSG3L.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace AdminSG3L.Infrastructure.Services
{
    /// <summary>
    /// 系统初始化服务
    /// 负责在系统启动时自动创建系统权限和角色
    /// </summary>
    public class SystemInitializationService
    {
        private readonly AdminDbContext _context;
        private readonly ILogger<SystemInitializationService> _logger;

        public SystemInitializationService(
            AdminDbContext context,
            ILogger<SystemInitializationService> logger)
        {
            _context = context;
            _logger = logger;
        }

        /// <summary>
        /// 初始化系统数据
        /// </summary>
        public async Task InitializeSystemDataAsync()
        {
            try
            {
                _logger.LogInformation("开始初始化系统数据...");
                _logger.LogWarning("注意：系统权限、角色、菜单为系统数据，不可删除或修改");

                // 初始化权限
                await InitializePermissionsAsync();

                // 初始化菜单
                await InitializeMenusAsync();

                // 初始化角色
                await InitializeRolesAsync();

                // 分配角色权限和菜单
                await AssignRolePermissionsAsync();

                // 创建默认超级管理员
                await CreateDefaultSuperAdminAsync();

                _logger.LogInformation("系统数据初始化完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "系统数据初始化失败");
                throw;
            }
        }

        /// <summary>
        /// 初始化系统权限
        /// </summary>
        private async Task InitializePermissionsAsync()
        {
            var systemPermissions = GetSystemPermissions();

            // 先创建一级权限（父权限）
            var parentPermissions = systemPermissions.Where(p => p.ParentCode == null).ToList();
            foreach (var permissionData in parentPermissions)
            {
                var existingPermission = await _context.Permissions
                    .FirstOrDefaultAsync(p => p.PermissionCode == permissionData.Code);

                if (existingPermission == null)
                {
                    var permission = AppPermission.Create(
                        permissionData.Name, 
                        permissionData.Code, 
                        permissionData.Description,
                        null,
                        true // 标记为系统权限
                    );

                    await _context.Permissions.AddAsync(permission);
                    _logger.LogInformation($"创建系统权限模块: {permission.PermissionName} ({permission.PermissionCode})");
                }
                else if (!existingPermission.IsSystem)
                {
                    // 只有非系统权限才允许更新为系统权限
                    existingPermission.Update(
                        permissionData.Name, 
                        permissionData.Code, 
                        permissionData.Description
                    );
                    // 手动设置为系统权限（因为Update方法不允许修改系统权限）
                    existingPermission.IsSystem = true;
                    _logger.LogInformation($"将现有权限标记为系统权限: {existingPermission.PermissionName} ({existingPermission.PermissionCode})");
                }
                // 如果已经是系统权限，跳过更新
                else
                {
                    _logger.LogDebug($"系统权限已存在，跳过更新: {existingPermission.PermissionName} ({existingPermission.PermissionCode})");
                }
            }

            await _context.SaveChangesAsync();

            // 再创建子权限
            var childPermissions = systemPermissions.Where(p => p.ParentCode != null).ToList();
            foreach (var permissionData in childPermissions)
            {
                var existingPermission = await _context.Permissions
                    .FirstOrDefaultAsync(p => p.PermissionCode == permissionData.Code);

                if (existingPermission == null)
                {
                    var parentPermission = await _context.Permissions
                        .FirstOrDefaultAsync(p => p.PermissionCode == permissionData.ParentCode);

                    var permission = AppPermission.Create(
                        permissionData.Name, 
                        permissionData.Code, 
                        permissionData.Description,
                        parentPermission?.Id,
                        true // 标记为系统权限
                    );

                    await _context.Permissions.AddAsync(permission);
                    _logger.LogInformation($"创建系统权限: {permission.PermissionName} ({permission.PermissionCode})");
                }
                else if (!existingPermission.IsSystem)
                {
                    // 只有非系统权限才允许更新为系统权限
                    var parentPermission = await _context.Permissions
                        .FirstOrDefaultAsync(p => p.PermissionCode == permissionData.ParentCode);
                    
                    existingPermission.Update(
                        permissionData.Name, 
                        permissionData.Code, 
                        permissionData.Description,
                        parentPermission?.Id
                    );
                    // 手动设置为系统权限
                    existingPermission.IsSystem = true;
                    _logger.LogInformation($"将现有子权限标记为系统权限: {existingPermission.PermissionName} ({existingPermission.PermissionCode})");
                }
                else
                {
                    _logger.LogDebug($"系统子权限已存在，跳过更新: {existingPermission.PermissionName} ({existingPermission.PermissionCode})");
                }
            }

            await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 初始化系统角色
        /// </summary>
        private async Task InitializeRolesAsync()
        {
            var systemRoles = GetSystemRoles();

            foreach (var roleData in systemRoles)
            {
                var existingRole = await _context.Roles
                    .FirstOrDefaultAsync(r => r.RoleCode == roleData.Code);

                if (existingRole == null)
                {
                    var role = AppRole.Create(
                        roleData.Name, 
                        roleData.Code, 
                        roleData.Description,
                        true // 标记为系统角色
                    );

                    await _context.Roles.AddAsync(role);
                    _logger.LogInformation($"创建系统角色: {role.RoleName} ({role.RoleCode})");
                }
                else if (!existingRole.IsSystem)
                {
                    // 只有非系统角色才允许更新为系统角色
                    existingRole.Update(
                        roleData.Name, 
                        roleData.Code, 
                        roleData.Description
                    );
                    // 手动设置为系统角色
                    existingRole.IsSystem = true;
                    _logger.LogInformation($"将现有角色标记为系统角色: {existingRole.RoleName} ({existingRole.RoleCode})");
                }
                else
                {
                    _logger.LogDebug($"系统角色已存在，跳过更新: {existingRole.RoleName} ({existingRole.RoleCode})");
                }
            }

            await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 初始化系统菜单
        /// </summary>
        private async Task InitializeMenusAsync()
        {
            var systemMenus = GetSystemMenus();

            // 先创建一级菜单
            var parentMenus = systemMenus.Where(m => m.ParentCode == null).ToList();
            foreach (var menuData in parentMenus)
            {
                var existingMenu = await _context.Menus
                    .FirstOrDefaultAsync(m => m.MenuCode == menuData.Code);

                if (existingMenu == null)
                {
                    var menu = AppMenu.Create(
                        menuData.Name, 
                        menuData.Code, 
                        null, null, null,
                        menuData.Icon, 
                        menuData.Path, 
                        menuData.Description,
                        true // 标记为系统菜单
                    );

                    await _context.Menus.AddAsync(menu);
                    _logger.LogInformation($"创建系统菜单: {menu.MenuName} ({menu.MenuCode})");
                }
            }

            await _context.SaveChangesAsync();

            // 再创建子菜单
            var childMenus = systemMenus.Where(m => m.ParentCode != null).ToList();
            foreach (var menuData in childMenus)
            {
                var existingMenu = await _context.Menus
                    .FirstOrDefaultAsync(m => m.MenuCode == menuData.Code);

                if (existingMenu == null)
                {
                    var parentMenu = await _context.Menus
                        .FirstOrDefaultAsync(m => m.MenuCode == menuData.ParentCode);

                    var menu = AppMenu.Create(
                        menuData.Name, 
                        menuData.Code, 
                        parentMenu?.Id, null, null,
                        menuData.Icon, 
                        menuData.Path, 
                        menuData.Description,
                        true // 标记为系统菜单
                    );

                    await _context.Menus.AddAsync(menu);
                    _logger.LogInformation($"创建系统子菜单: {menu.MenuName} ({menu.MenuCode})");
                }
            }

            await _context.SaveChangesAsync();
        }
        /// <summary>
        /// 分配角色权限和菜单
        /// </summary>
        private async Task AssignRolePermissionsAsync()
        {
            var rolePermissionMappings = GetRolePermissionMappings();
            var roleMenuMappings = GetRoleMenuMappings();

            foreach (var mapping in rolePermissionMappings)
            {
                var role = await _context.Roles
                    .Include(r => r.Permissions)
                    .Include(r => r.Menus)
                    .FirstOrDefaultAsync(r => r.RoleCode == mapping.RoleCode);

                if (role == null) continue;

                // 清除现有权限分配（仅对系统角色）
                role.Permissions.Clear();

                // 分配权限
                foreach (var permissionCode in mapping.PermissionCodes)
                {
                    var permission = await _context.Permissions
                        .FirstOrDefaultAsync(p => p.PermissionCode == permissionCode);

                    if (permission != null)
                    {
                        role.AddPermission(permission);
                        _logger.LogDebug($"分配权限 {permissionCode} 给角色 {mapping.RoleCode}");
                    }
                }

                // 分配菜单
                var menuMapping = roleMenuMappings.FirstOrDefault(m => m.RoleCode == mapping.RoleCode);
                if (menuMapping.MenuCodes != null)
                {
                    // 清除现有菜单分配
                    role.Menus.Clear();

                    foreach (var menuCode in menuMapping.MenuCodes)
                    {
                        var menu = await _context.Menus
                            .FirstOrDefaultAsync(m => m.MenuCode == menuCode);

                        if (menu != null)
                        {
                            role.AddMenu(menu);
                            _logger.LogDebug($"分配菜单 {menuCode} 给角色 {mapping.RoleCode}");
                        }
                    }
                }
            }

            await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 获取系统权限定义
        /// </summary>
        private List<PermissionData> GetSystemPermissions()
        {
            return new List<PermissionData>
            {
                // 一级权限模块
                new("仪表盘模块", "dashboard", "仪表盘相关功能权限", null),
                new("用户管理模块", "user", "用户管理相关功能权限", null),
                new("角色管理模块", "role", "角色管理相关功能权限", null),
                new("权限管理模块", "permission", "权限管理相关功能权限", null),
                new("菜单管理模块", "menu", "菜单管理相关功能权限", null),
                new("数据分析模块", "analytics", "数据分析相关功能权限", null),
                new("日志管理模块", "log", "日志管理相关功能权限", null),
                new("监控管理模块", "monitoring", "监控管理相关功能权限", null),
                new("模板管理模块", "template", "模板管理相关功能权限", null),
                new("组件管理模块", "component", "组件管理相关功能权限", null),
                new("个人中心模块", "profile", "个人中心相关功能权限", null),

                // 仪表盘权限
                new("仪表盘查看", "dashboard.view", "访问系统仪表盘页面", "dashboard"),
                new("实时数据仪表盘", "dashboard.realtime", "访问实时数据监控页面", "dashboard"),

                // 用户管理权限
                new("查看用户列表", "user.view", "查看用户列表和用户详情", "user"),
                new("创建新用户", "user.create", "创建新用户账户", "user"),
                new("编辑用户信息", "user.update", "修改用户基本信息", "user"),
                new("删除用户", "user.delete", "删除用户账户", "user"),
                new("分配用户角色", "user.assign", "为用户分配或移除角色", "user"),
                new("重置密码", "user.resetPassword", "重置其他用户的密码", "user"),
                new("用户搜索", "user.search", "使用高级筛选搜索用户", "user"),

                // 角色管理权限
                new("查看角色列表", "role.view", "查看角色列表和角色详情", "role"),
                new("创建新角色", "role.create", "创建新的系统角色", "role"),
                new("编辑角色信息", "role.update", "修改角色基本信息", "role"),
                new("删除角色", "role.delete", "删除系统角色", "role"),
                new("分配角色权限", "role.assign", "为角色分配权限", "role"),
                new("配置角色菜单", "role.menu", "配置角色可访问的菜单", "role"),
                new("启用/禁用角色", "role.status", "启用/禁用角色", "role"),

                // 权限管理权限
                new("查看权限列表", "permission.view", "查看权限列表和权限树", "permission"),
                new("创建新权限", "permission.create", "创建新的系统权限", "permission"),
                new("编辑权限信息", "permission.update", "修改权限信息", "permission"),
                new("删除权限", "permission.delete", "删除系统权限", "permission"),
                new("权限树管理", "permission.tree", "管理权限的层级结构", "permission"),
                new("启用/禁用权限", "permission.status", "启用/禁用权限", "permission"),

                // 菜单管理权限
                new("查看菜单列表", "menu.view", "查看菜单列表和菜单结构", "menu"),
                new("创建新菜单", "menu.create", "创建新的系统菜单", "menu"),
                new("编辑菜单信息", "menu.update", "修改菜单信息和结构", "menu"),
                new("删除菜单", "menu.delete", "删除系统菜单", "menu"),
                new("菜单排序", "menu.sort", "调整菜单显示顺序", "menu"),
                new("菜单分配到角色", "menu.assign", "将菜单分配到角色", "menu"),

                // 数据分析权限
                new("数据分析仪表盘", "analytics.dashboard", "访问数据分析中心", "analytics"),
                new("图表查看", "analytics.chart", "查看各种数据图表", "analytics"),
                new("实时数据分析", "analytics.realtime", "查看实时数据分析", "analytics"),

                // 日志管理权限
                new("查看系统日志", "log.view", "查看系统操作日志", "log"),
                new("清空日志", "log.delete", "清空或删除日志记录", "log"),
                new("日志搜索筛选", "log.search", "搜索和筛选日志", "log"),

                // 监控管理权限
                new("系统监控", "monitoring.system", "查看系统性能监控", "monitoring"),
                new("性能监控", "monitoring.performance", "查看性能指标数据", "monitoring"),
                new("告警管理", "monitoring.alerts", "管理系统告警规则", "monitoring"),

                // 模板组件权限
                new("查看模板中心", "template.view", "查看模板中心内容", "template"),
                new("创建新模板", "template.create", "创建新的模板", "template"),
                new("编辑模板", "template.edit", "修改模板内容", "template"),
                new("删除模板", "template.delete", "删除模板", "template"),

                // 组件管理权限
                new("查看组件中心", "component.view", "查看组件中心内容", "component"),
                new("组件管理", "component.manage", "管理组件库", "component"),

                // 个人中心权限
                new("个人资料查看", "profile.view", "查看个人资料", "profile"),
                new("更新个人信息", "profile.update", "更新个人信息", "profile")
            };
        }

        /// <summary>
        /// 获取系统菜单定义
        /// </summary>
        private List<MenuData> GetSystemMenus()
        {
            return new List<MenuData>
            {
                // 一级菜单
                new("dashboard", "仪表盘", "Dashboard", "/dashboard", "系统仪表盘", null),
                new("analytics", "数据分析", "BarChart", "/analytics", "数据分析页面", null),
                new("monitoring", "系统监控", "Monitor", "/monitoring", "系统监控页面", null),
                new("templates", "模板中心", "Document", "/templates", "模板中心", null),
                new("components", "组件中心", "Grid", "/components", "组件中心", null),
                new("system", "系统管理", "Setting", "/system", "系统管理模块", null),
                new("logs", "日志中心", "Document", "/logs", "系统日志管理", null),
                new("profile", "个人资料", "User", "/profile", "个人资料管理", null),

                // 系统管理子菜单
                new("users", "用户管理", "User", "/system/users", "用户管理页面", "system"),
                new("roles", "角色管理", "UserGroup", "/system/roles", "角色管理页面", "system"),
                new("permissions", "权限管理", "Lock", "/system/permissions", "权限管理页面", "system"),
                new("menus", "菜单管理", "Menu", "/system/menus", "菜单管理页面", "system")
            };
        }

        /// <summary>
        /// 获取系统角色定义
        /// </summary>
        private List<(string Name, string Code, string Description)> GetSystemRoles()
        {
            return new List<(string, string, string)>
            {
                ("超级管理员", "super_admin", "系统最高权限，拥有所有功能的完全访问权限"),
                ("系统管理员", "system_admin", "负责日常系统管理和用户管理"),
                ("数据分析师", "data_analyst", "专注于数据分析和报表生成"),
                ("运维人员", "devops", "负责系统运维和监控"),
                ("开发者", "developer", "负责模板和组件的开发管理"),
                ("普通用户", "regular_user", "系统的普通使用者")
            };
        }

        /// <summary>
        /// 获取角色权限映射关系
        /// </summary>
        private List<(string RoleCode, string[] PermissionCodes)> GetRolePermissionMappings()
        {
            return new List<(string, string[])>
            {
                ("super_admin", new[]
                {
                    "dashboard.view", "dashboard.realtime",
                    "user.view", "user.create", "user.update", "user.delete", "user.assign", "user.resetPassword", "user.search",
                    "role.view", "role.create", "role.update", "role.delete", "role.assign", "role.menu", "role.status",
                    "permission.view", "permission.create", "permission.update", "permission.delete", "permission.tree", "permission.status",
                    "menu.view", "menu.create", "menu.update", "menu.delete", "menu.sort", "menu.assign",
                    "analytics.dashboard", "analytics.chart", "analytics.realtime",
                    "log.view", "log.delete", "log.search",
                    "monitoring.system", "monitoring.performance", "monitoring.alerts",
                    "template.view", "template.create", "template.edit", "template.delete",
                    "component.view", "component.manage",
                    "profile.view", "profile.update"
                }),
                ("system_admin", new[]
                {
                    "dashboard.view",
                    "user.view", "user.create", "user.update", "user.assign", "user.search",
                    "role.view", "role.assign",
                    "permission.view",
                    "menu.view",
                    "analytics.dashboard", "analytics.chart",
                    "log.view",
                    "monitoring.system",
                    "template.view",
                    "component.view",
                    "profile.view", "profile.update"
                }),
                ("data_analyst", new[]
                {
                    "dashboard.view", "dashboard.realtime",
                    "analytics.dashboard", "analytics.chart", "analytics.realtime",
                    "user.view",
                    "role.view",
                    "log.view",
                    "monitoring.system",
                    "profile.view", "profile.update"
                }),
                ("devops", new[]
                {
                    "dashboard.view",
                    "monitoring.system", "monitoring.performance", "monitoring.alerts",
                    "log.view", "log.search",
                    "analytics.dashboard",
                    "profile.view", "profile.update"
                }),
                ("developer", new[]
                {
                    "dashboard.view",
                    "template.view", "template.create", "template.edit",
                    "component.view", "component.manage",
                    "user.view",
                    "role.view",
                    "analytics.chart",
                    "profile.view", "profile.update"
                }),
                ("regular_user", new[]
                {
                    "dashboard.view",
                    "template.view",
                    "component.view",
                    "analytics.chart",
                    "profile.view", "profile.update"
                })
            };
        }

        /// <summary>
        /// 获取角色菜单映射关系
        /// </summary>
        private List<(string RoleCode, string[] MenuCodes)> GetRoleMenuMappings()
        {
            return new List<(string, string[])>
            {
                ("super_admin", new[]
                {
                    "dashboard", "analytics", "monitoring", "templates", "components",
                    "system", "users", "roles", "permissions", "menus", "logs", "profile"
                }),
                ("system_admin", new[]
                {
                    "dashboard", "analytics", "templates", "components",
                    "system", "users", "roles", "permissions", "logs", "profile"
                }),
                ("data_analyst", new[]
                {
                    "dashboard", "analytics", "monitoring", "profile"
                }),
                ("devops", new[]
                {
                    "dashboard", "monitoring", "logs", "analytics", "profile"
                }),
                ("developer", new[]
                {
                    "dashboard", "templates", "components", "analytics", "profile"
                }),
                ("regular_user", new[]
                {
                    "dashboard", "templates", "components", "analytics", "profile"
                })
            };
        }

        /// <summary>
        /// 创建默认超级管理员
        /// </summary>
        private async Task CreateDefaultSuperAdminAsync()
        {
            const string defaultAdminUsername = "superadmin";
            const string defaultAdminPassword = "Admin@123456";
            const string defaultAdminEmail = "superadmin@system.local";

            // 检查是否已存在超级管理员
            var existingSuperAdmin = await _context.Users
                .FirstOrDefaultAsync(u => u.Username == defaultAdminUsername);

            if (existingSuperAdmin == null)
            {
                // 获取超级管理员角色
                var superAdminRole = await _context.Roles
                    .Include(r => r.Users)
                    .FirstOrDefaultAsync(r => r.RoleCode == "super_admin");

                if (superAdminRole != null)
                {
                    var superAdmin = AppUser.Create(
                        "系统超级管理员",
                        defaultAdminUsername,
                        defaultAdminPassword,
                        defaultAdminEmail,
                        "/avatars/superadmin.png",
                        "系统默认超级管理员账户，不可删除",
                        true // 标记为系统用户
                    );

                    await _context.Users.AddAsync(superAdmin);
                    await _context.SaveChangesAsync();

                    // 分配超级管理员角色
                    superAdminRole.Users.Add(superAdmin);
                    await _context.SaveChangesAsync();

                    _logger.LogInformation($"创建默认超级管理员: {superAdmin.Username}");
                    _logger.LogWarning($"默认超级管理员密码: {defaultAdminPassword} - 请在首次登录后修改密码");
                }
                else
                {
                    _logger.LogError("无法创建默认超级管理员：未找到super_admin角色");
                }
            }
            else
            {
                _logger.LogInformation("默认超级管理员已存在，跳过创建");
            }
        }

        /// <summary>
        /// 菜单数据结构
        /// </summary>
        private record MenuData(string Code, string Name, string Icon, string Path, string Description, string? ParentCode);

        /// <summary>
        /// 权限数据结构
        /// </summary>
        private record PermissionData(string Name, string Code, string Description, string? ParentCode);
    }
}
